package com.lt.crypto;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class HmacShaUtils
{
    public static String HmacSHA1Encrypt(String encryptText, String encryptKey) {
        byte[] data = encryptKey.getBytes();
        SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        try {
            mac.init(secretKey);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        byte[] text = encryptText.getBytes();
        return bytesToHexString(mac.doFinal(text));
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static String HmacSHA1Encrypt(HashMap<String, String> paramsMap,
                                         String encryptKey) {
        List<Map.Entry<String, String>> paramsList = new ArrayList<Map.Entry<String, String>>(
                paramsMap.entrySet());
        Collections.sort(paramsList,
                new Comparator<Map.Entry<String, String>>() {
                    @Override
                    public int compare(Map.Entry<String, String> o1,
                                       Map.Entry<String, String> o2) {
                        return o1.getKey().toString()
                                .compareTo(o2.getKey().toString());
                    }
                });
        String data = "";
        for (int i = 0; i < paramsList.size(); i++) {
            data += paramsList.get(i).toString() + ";";
        }
        return HmacSHA1Encrypt(data, encryptKey);
    }

    public static String HmacSHA1Encrypt(String appid, Long timestamp,
                                         String encryptKey) {
        String encryptText = appid + ":" + timestamp.toString();
        return HmacSHA1Encrypt(encryptText, encryptKey);
    }

    public static String HmacSHA1EncryptV2(HashMap<String, String> paramsMap,
                                           String encryptKey) {
        List<Map.Entry<String, String>> paramsList = new ArrayList<Map.Entry<String, String>>(
                paramsMap.entrySet());
        Collections.sort(paramsList,
                new Comparator<Map.Entry<String, String>>() {
                    @Override
                    public int compare(Map.Entry<String, String> o1,
                                       Map.Entry<String, String> o2) {
                        return o1.getKey().toString()
                                .compareTo(o2.getKey().toString());
                    }
                });
        String data = "";
        for (int i = 0; i < paramsList.size(); i++) {
            if (paramsList.get(i).getValue().toString().equals("null")) {
                data += "";
            } else {
                data += paramsList.get(i).toString();
            }
        }
        return HmacSHA1Encrypt(data, encryptKey);
    }

}
